#ifndef STLCONTOURWIDGET_H
#define STLCONTOURWIDGET_H

#include <QWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QFile>
#include <QWheelEvent>

#include "ModelFormation.h"
#include "STLReader.h"
#include "STLModelMeshesConvertor.h"
#include "STLModelSlicesProducer.h"
#include "STLModelAttributesCalculator.h"
#include "SliceContoursExtractor.h"
#include "ViewCamera.h"

struct ContourInfo
{
    QVector3D plane_norm = QVector3D();
    QVector3D camera_up = QVector3D();
    float distance = 70.0f;
    float lambda = 0.1f;
};

class STLContourWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    STLContourWidget(std::shared_ptr<STLReader> stl_reader, const ContourInfo& contour_info, QWidget *parent);
    ~STLContourWidget();

public:
    void wheelEvent(QWheelEvent *event) override;

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    bool loadShaderSource(const QString &filePath, QString &source);
    bool compileAndLinkShaders(QOpenGLShaderProgram *p_program, const QString &vs_file_path, const QString &fs_file_path);
    void setContourShaderProgramDataFormation();
    void setContourVertexData2Shader(const QVector<Vertex> &contour_vertices);
    void updateContourIndexRangeInfo(GLint &contour_head, GLint &count, bool increaseOrDecrease);
    void calAndSetModelInitPhase(bool isFlip = false);

private:
    float m_camera_dis = 0.0f;
    float m_slice_lambda = 0.0f;
    QVector3D m_plane_norm = QVector3D();
    QVector3D m_camera_up = QVector3D();
    QVector<qsizetype> m_intersected_points_counts;
    GLint m_contourHead = 0;
    GLint m_contourPointsCount = 0;
    qsizetype m_curShowContourIndice = 0;
    QVector<QVector<Vertex>> m_contours;

private:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram *m_p_program = nullptr;

private:
    std::shared_ptr<STLReader> m_sp_stl_reader = nullptr;
    STLModelAttributesCalculator m_model_attr_calculator;

private:
    QMatrix4x4 m_model;
    QVector3D m_centroid;
    QVector3D m_initModelPhase;
    ViewCamera m_camera;
};

#endif // STLCONTOURWIDGET_H
